
	.386
if ?FLAT
	.MODEL FLAT, stdcall
else
	.MODEL SMALL, stdcall
endif
	option casemap:none
	option proc:private

	include winbase.inc
	include dkrnl32.inc
	include macros.inc

	.CODE

;--- returns:
;--- DRIVE_UNKNOWN
;--- DRIVE_NO_ROOT_DIR
;--- DRIVE_FIXED
;--- DRIVE_REMOVABLE
;--- DRIVE_REMOTE (network)
;--- DRIVE_CDROM
;--- DRIVE_RAMDISK

GetDriveTypeA proc public uses ebx pRoot:ptr BYTE

	mov eax,pRoot
	and eax,eax
	jz @F
	mov ax,[eax]
	cmp ah,':'
	jnz @F
	or al,20h
	sub al,'a'
	jmp sm1
@@:
	mov ah,19h
	int 21h
sm1:
	inc al
	mov bl,al
	mov ax,4409h	;check if drive remote
	int 21h
	jc isinvalid
	cmp bl,2		;A:,B: special handling
	ja @F

;--- perhaps better to call int 21h, ax=4408h ( is drive removable? )

	push dx
	mov ax,440Eh	;get logical drive map
	int 21h
	pop dx
	cmp al,00
	jz isremovable
	cmp al,bl
	jz isremovable
;	jmp isinvalid

@@:
	and dh,not 40h
	cmp dx,0800h	;pretty good test for a ramdisk
	jz isramdisk
	test dh,10h		;bit 12 of dx - remote?
	jz isfixed
	mov cl,bl
	dec cl
	mov ch,0
	mov ax,150bh
	int 2Fh
	cmp bx,0ADADh
	jnz isremote
	and ax,ax
	jz isremote
iscdrom:
	mov eax,DRIVE_CDROM
	jmp exit
isremovable:
	mov eax,DRIVE_REMOVABLE
	jmp exit
isramdisk:
	mov eax,DRIVE_RAMDISK
	jmp exit
isremote:
	mov eax,DRIVE_REMOTE
	jmp exit
isinvalid:
	mov eax,DRIVE_NO_ROOT_DIR
	jmp exit
isfixed:
	mov eax,DRIVE_FIXED
exit:
	@strace <"GetDriveTypeA('", &pRoot, "')=", eax>
	ret
	align 4

GetDriveTypeA endp

GetDriveTypeW proc public pRoot:ptr WORD
	mov eax, pRoot
	call ConvertWStr
	invoke GetDriveTypeA, eax
	@strace <"GetDriveTypeW(", pRoot, ")=", eax>
	ret
	align 4
GetDriveTypeW endp

GetLogicalDrives proc public uses ebx esi

	xor esi,esi
	mov bl,01
next:
if 0
	mov ax,4408h		 ;check if drive removeable
	int 21h
	jc @F
else
	mov eax,"\: "
	mov al,bl
	add al,'A'-1
	push eax
	invoke GetDriveTypeA, esp
	pop ecx
	cmp eax, DRIVE_NO_ROOT_DIR
	jz @F
endif
	mov al,bl
	dec al
	movzx eax,al
	bts esi,eax
@@:
	inc bl
	cmp bl,20h
	jb next
	mov eax,esi
	@strace <"GetLogicalDrives()=", eax>
	ret
	align 4

GetLogicalDrives endp

GetLogicalDriveStringsA proc public uses edi nBufferLength:dword, lpBuffer:ptr BYTE

	invoke GetLogicalDrives
	mov ecx, nBufferLength
	mov edi, lpBuffer
	mov edx, "\:A"
	.while (eax)
		.if (al & 1)
			.if (ecx >= 4)
				mov [edi],edx
				sub ecx, 4
			.else
				xor ecx, ecx
			.endif
			add edi, 4
		.endif
		inc dl
		shr eax, 1
	.endw
	mov eax, edi
	.if (ecx)
		mov byte ptr [edi],0
	.endif
	sub eax, lpBuffer
	@strace <"GetLogicalDriveStringsA(", nBufferLength, ", ", lpBuffer, ")=", eax>
	ret
	align 4
GetLogicalDriveStringsA endp

	end
